package cn.gzmli.dtt.common.service;


import cn.gzmli.dtt.common.config.cache.Config;
import cn.gzmli.dtt.common.dao.FileUploadDao;
import cn.gzmli.dtt.common.entity.FileUpload;
import cn.gzmli.dtt.common.entity.PageInfo;
import cn.gzmli.dtt.common.entity.Result;
import cn.gzmli.dtt.common.utils.*;
import com.xiaoleilu.hutool.util.StrUtil;
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;

/**
 * @desc 文件上传业务处理Services
 *
 * @author Pyj
 * @date 20190828
 */
@Service
public class FileUploadSerivce extends BaseService<FileUpload> {

    Logger logger = LoggerFactory.getLogger(FileUploadSerivce.class);

    public static String sFilePath="D:/files";

    @Autowired
    FileUploadDao fileUploadDao;

    public List getFilesList(HttpServletRequest request, PageInfo pageInfo) throws Exception {
        return  fileUploadDao.getFilesList(request,pageInfo);
    }

    public FileUpload getFileUpload(Integer fileId,String url, String scalePath) throws Exception {
        FileUpload fileUpload;
        if (BaseUtil.isNotEmpty(fileId) && fileId != 0) {
            fileUpload = getFileById(fileId);
        } else if (StrUtil.isNotBlank(url) && !"0".equals(url)) {
            // 根据文件相对路径查询
            fileUpload = getFilesUploadByURL(url);
        } else if (StrUtil.isNotBlank(scalePath) && !"0".equals(url)) {
            // 根据文件缩放图路径查询
            fileUpload = getFilesUploadByScalePath(scalePath);
        } else {
            fileUpload = null;
        }
        return fileUpload;
    }

    public FileUpload getFileById(Integer fileId) throws Exception {
        return (FileUpload)fileUploadDao.get(fileId);
    }

    public FileUpload getFilesUploadByURL(String url) throws Exception {
        return fileUploadDao.getFilesUploadByURL(url);
    }

    /**
     * 根据文件缩放图路径查询
     * @param scalePath
     * @return
     * @throws Exception
     */
    public FileUpload getFilesUploadByScalePath(String scalePath) throws Exception {
        return fileUploadDao.getFilesUploadByScalePath(scalePath);
    }

    /**
     * 文件上传
     *
     * @param request
     * @param file          文件流
     * @param isScale       是否压缩
     * @return
     * @throws Exception
     */
    public Result upload(HttpServletRequest request, MultipartFile file, Boolean isScale)
            throws Exception {
        Result result = new Result();
        FileUpload fileUpload = new FileUpload();

        String filePath = sFilePath; //绝对路径
        String relativePath = ""; //相对路径
        String fileName = file.getOriginalFilename(); //文件名称
        String suffixName = fileName.substring(file.getOriginalFilename().lastIndexOf(".")); //文件类型

        try {
            if (file == null || file.isEmpty()) {
                result.setStatus(Constant.FAIL);
                result.setMsg("文件不能为空！");
                return result;
            }
            // 后缀名校验及检验文件安全,防止上传攻击性文件
            boolean upFlag = FileUtils.getUpFileLegitimacyFlag(file);
            if (!upFlag) {
                result.setStatus(Constant.FAIL);
                result.setMsg("文件不合法！");
                return result;
            }

            if(isScale == null) {
                isScale = true; //同时默认生成压缩图片
            }

            Boolean isCatalog = true; //默认按日期分类


            if(StrUtil.isNotBlank(fileName)){
                // 解决中文问题,liunx下中文路径,图片显示问题
                fileName = UUID.randomUUID().toString().replaceAll("\\-","") + suffixName;
            }

            if(isCatalog){//按时间目录分类
                String timeDir = DateUtils.getDay();
                filePath += "/"+timeDir;
                relativePath += "/"+timeDir;
            }

            File dest = new File(filePath + "/" + fileName);

            if(dest.exists()){//判断文件是否存在
                //删除已存在文件，随后执行替换操作
                dest.delete();
            }

            if (!dest.getParentFile().exists()) {//检测是否存在目录
                dest.getParentFile().mkdirs();//新建文件夹
            }

            //TODO 将文件写入到指定目录
            file.transferTo(dest);

            // 判断是否图片,并且是否压缩
            Boolean flag = ImageUtils.isImage(suffixName);
            // 基于thumbnailator实现图片（缩放，剪切，水印）处理
            if (flag && isScale) {
                String thumbnailUrl;	// 缩略图地址
                int dot = fileName.lastIndexOf(".");
                String thumbnailName = fileName.substring(0, dot)+"-thumbnail"+suffixName;

                String thumDirPath = filePath + "/scale/";
                File thumbnailDir = new File(thumDirPath);

                if (!thumbnailDir.exists()) {
                    // 若目录不存在,则直接创建目录
                    thumbnailDir.mkdirs();
                }

                File thumbnailFile = new File(thumDirPath + thumbnailName);
                BufferedImage originalImage = ImageIO.read(dest);
                //Thumbnails.of(originalImage).size(200,200).toFile(thumbnailFile);//按固定长宽缩放,单位为像素
                Thumbnails.of(originalImage).scale(0.6).toFile(thumbnailFile);//按比例缩放
                thumbnailUrl = relativePath + "/scale/" + thumbnailName;
                fileUpload.setIsScale(1);
                fileUpload.setScalePath(thumbnailUrl);
            }

            //保存文件对象
            fileUpload.setName(file.getOriginalFilename());
            fileUpload.setType(suffixName);
            fileUpload.setSize(String.valueOf(dest.length()));
            fileUpload.setPath(filePath + "/" + fileName);
            fileUpload.setUrl(relativePath + "/" + fileName);
            fileUpload.setStatus(1);
            fileUpload.setCreatorId(Config.getUser(request).getId());
            fileUpload.setCreateTime(new Date());
            Serializable id = fileUploadDao.insert(fileUpload);

            Map<String,Object> resultMap = new HashMap<String,Object>();
            resultMap.put("id", id);
            resultMap.put("name", fileName);
            resultMap.put("url", fileUpload.getUrl());
            resultMap.put("type", fileUpload.getType());
            resultMap.put("size", dest.length());
            resultMap.put("scaleUrl", fileUpload.getScalePath());
            result.setStatus(Constant.SUCCESS);
            result.setMsg("文件上传成功！");
            result.setData(resultMap);
            return result;
        } catch (IOException e) {
            //e.printStackTrace();

            //若文件上传报错，直接删除文件
            File fe = new File(filePath);
            if (FileUtils.deleteFile(fe)) {
                logger.info("======文件删除成功======");
                result.setMsg("文件上传失败: "+e.getMessage());
                result.setStatus(Constant.FAIL);
            } else {
                logger.info("======删除文件失败,该文件不存在======");
            }
            return result;
        }

    }

    /**
     * 文件删除
     *
     * @param request
     * @param fileId       文件id
     * @return
     * @throws Exception
     */
    public boolean deleteFile(HttpServletRequest request, Integer fileId,String url, String scalePath)throws Exception {
        FileUpload fileUpload = getFileUpload(fileId,url,scalePath);
        if(fileUpload==null){
            return false;
        }

        File file = new File(fileUpload.getPath());
        if(file.exists()){
            file.delete();
        }
        String sPath = sFilePath+fileUpload.getScalePath();
        File scaleFile = new File(sPath);
        if(scaleFile.exists()){
            scaleFile.delete();
        }
        fileUploadDao.delete(fileUpload);
        return true;
    }
}
